package beans;

import entidades.Processo;
import entidades.Usuario;
import excessoes.DAOException;
import excessoes.FabricaDAOException;
import excessoes.RNException;
import excessoes.UtilException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.NotSerializableException;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;
import rn.ProcessoRN;
import util.ContextoUtil;
import util.FacesUtil;

/**
 *
 * @author Marcelo Gomes Neto
 */
/*
@ViewScoped = Instancia do bean é criada e mantida enquanto o usuário estiver na página (por exemplo, com os manipuladores de eventos ou Ajax). Deve implementar Serializable
@SessionScoped = Criado um por sessão de cada usuário.
@ApplicationScoped = Criado um para toda a aplicação.
@RequestScoped = Escopo padrão. É criado a cada requisição. 
 */
@ManagedBean(name="processoBean")
@ViewScoped
public class ProcessoBean implements Serializable 
{
    private static final long serialVersionUID = 3193845720397426615L;
    private Processo processo = new Processo();
    private List<Processo> listarProcessoPorStatus;
    private Date dataAtual;
    private Integer filtroSelecionado;
    private UploadedFile uploadArquivo;
    private String nomeArquivoSelecionado;
    private StreamedContent arquivoRetornoPAG;
    private String motivo;
    
    public ProcessoBean() {}
    
    public void prepararAdicionarProcesso(ActionEvent actionEvent) {
        this.processo = new Processo();
        this.setNomeArquivoSelecionado(null);
    }

    public void editar() 
    {
        Integer id = this.processo.getIdprocesso();
        Boolean presente = this.processo.isArquivo();

        if (presente == Boolean.TRUE) {
            this.setNomeArquivoSelecionado(id+".pdf");
        }
        else {
            this.setNomeArquivoSelecionado(null);
        }
    }
    
    public String excluir() throws RNException, DAOException, FabricaDAOException, Exception 
    {
        ContextoBean contextoBean = ContextoUtil.getContextoBean();
        Usuario usuario = contextoBean.getUsuarioLogado();
        ProcessoRN processoRN = new ProcessoRN();
        processoRN.excluirProcesso(this.processo, usuario);
        this.setListarProcessoPorStatus(processoRN.listarProcessoPorStatus(this.filtroSelecionado));
        this.processo = new Processo();
        //this.setListarSolicitacoes(solicitacaoRN.listar());
        return null;
    }

    // ARQUIVO OU DESARQUIVA PROCESSO
    public String manter() throws DAOException, Exception 
    {
        ContextoBean contextoBean = ContextoUtil.getContextoBean();
        Usuario usuario = contextoBean.getUsuarioLogado();
        ProcessoRN processoRN = new ProcessoRN();
        this.processo.setMotivoArquivamento(this.motivo);
        processoRN.manterProcesso(this.processo, usuario);
        this.setListarProcessoPorStatus(processoRN.listarProcessoPorStatus(this.filtroSelecionado));
        this.processo = new Processo();
        this.setMotivo(null);
        return null;
        //return "/restrito/processos.xhtml"; 
    }

    // Método utilizado no arquivo /admin/processo.xhtm para voltar para lista_processos.xhtml
    public String salvar() throws Exception 
    {
        try 
        {
            ContextoBean contextoBean = ContextoUtil.getContextoBean();
            Usuario usuario = contextoBean.getUsuarioLogado();
            ProcessoRN processoRN = new ProcessoRN();

            if (this.nomeArquivoSelecionado == null || this.nomeArquivoSelecionado.equals("")) {
                this.processo.setArquivo(false);
            }
            else {
                this.processo.setArquivo(true);
            }
            processoRN.salvarProcesso(this.processo, usuario);
            this.setListarProcessoPorStatus(processoRN.listarProcessoPorStatus(this.filtroSelecionado));
            this.setNomeArquivoSelecionado(null);
            this.processo = new Processo();
            //return "/restrito/processo/manter/manter_processos.xhtml"; 
        }
        catch (Exception e) {
        }
        return null;
    }
    
    public void setArquivoRetornoPAG(StreamedContent arquivoRetornoPAG) {
        this.arquivoRetornoPAG = arquivoRetornoPAG;
    }
    
    public StreamedContent getArquivoRetornoPAG() throws NotSerializableException, UtilException
    {
        try
        {
            Integer id = this.processo.getIdprocesso();
            String local = FacesUtil.getServletContext().getRealPath("/downloads/"+id+".pdf");
            InputStream conteudoRelatorio = new FileInputStream(local);
            this.arquivoRetornoPAG = new DefaultStreamedContent(conteudoRelatorio, "application/pdf", "PAG_"+id+".pdf");
        }
        catch (FileNotFoundException e) {
            throw new UtilException("Arquivo não encontrado: "+e.getMessage());
	}
        return this.arquivoRetornoPAG;
    }

    public Integer getFiltroSelecionado() {
        return filtroSelecionado;
    }

    public void setFiltroSelecionado(Integer filtroSelecionado) {
        this.filtroSelecionado = filtroSelecionado;
    }

    public List<Processo> getListarProcessoPorStatus() 
    {
        ProcessoRN processoRN = new ProcessoRN();
        if (this.filtroSelecionado != null) {
            this.setListarProcessoPorStatus(processoRN.listarProcessoPorStatus(this.filtroSelecionado));
        }
        return listarProcessoPorStatus;
    }

    public void setListarProcessoPorStatus(List<Processo> listarProcessoPorStatus) {
        this.listarProcessoPorStatus = listarProcessoPorStatus;
    }

    public UploadedFile getUploadArquivo() {
        return uploadArquivo;
    }

    public void setUploadArquivo(UploadedFile uploadArquivo) {
        this.uploadArquivo = uploadArquivo;
    }
    
    public String getNomeArquivoSelecionado() {
        return nomeArquivoSelecionado;
    }

    public void setNomeArquivoSelecionado(String nomeArquivoSelecionado) {
        this.nomeArquivoSelecionado = nomeArquivoSelecionado;
    }
    
    public String fileUploadAction(FileUploadEvent event) throws IOException, NotSerializableException, Exception 
    {
        ProcessoRN processoRN = new ProcessoRN();
        Integer id = processoRN.retornaUltimoID()+1;

        Integer idArq = this.processo.getIdprocesso();
        String local = null;
        //System.out.println("O IdArq é: "+idArq);
        
        if (idArq != null) {
            this.setNomeArquivoSelecionado(event.getFile().getFileName());
            local = FacesUtil.getServletContext().getRealPath("/downloads/"+idArq+".pdf");
        }
        else {
            this.setNomeArquivoSelecionado(event.getFile().getFileName());
            local = FacesUtil.getServletContext().getRealPath("/downloads/"+id+".pdf");
        }
        
        //Cria um arquivo UploadFile, para receber o arquivo do evento
        this.uploadArquivo = event.getFile();
        InputStream in = new BufferedInputStream(this.uploadArquivo.getInputstream());
        //copiar para pasta do projeto
        File file = new File(local); 
        FileOutputStream fout = null;
        try {
            fout = new FileOutputStream(file);
                
            while(in.available() != 0){
                fout.write(in.read());
            }
            fout.close();
         }
        catch (IOException io){
            FacesUtil.getFacesContext().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Não foi possível salvar o arquivo!", ""));
        }
        return null;
    }

    public String getMotivo() {
        return motivo;
    }

    public void setMotivo(String motivo) {
        this.motivo = motivo;
    }

    // Exibe a data atual no campo Data de Cadastramento ao incluir uma nova solicitação.
    public Date getDataAtual() {
        this.dataAtual = new Date(System.currentTimeMillis());
        return this.dataAtual;
    }

    public void setDataAtual(Date dataAtual) {
        this.dataAtual = dataAtual;
    }
    
    public Processo getProcesso() {
        return processo;
    }

    public void setProcesso(Processo processo) {
        this.processo = processo;
    }
} 